<?php

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

namespace BLL\DAO;

use BLL\DataModel as DM;
/**
 * Description of ImportContractGenerator
 *
 * @author David Wu
 */
class ImportContractGenerator {
    private $helper = null;
    public static $outputPath = null;
    //put your code here
    public function __construct(DM\DataContractHelper $helper) {
        $this->helper = $helper->dataContract;
        if (!self::$outputPath) {
            self::$outputPath = app_path() . DIRECTORY_SEPARATOR . "models" . DIRECTORY_SEPARATOR . "DataContract" . DIRECTORY_SEPARATOR;
        }
    }
    
    // helper->sourceType === "Input"
    public function generateFromGPC() {
        if ($this->helper["sourceType"] !== "Input")return;

        $str = "<?php\r\n";
        foreach ($this->helper["Target"] as $target) {
            if ($target["type"] === "Model") {
                $model = DM\DataNodeDescription::getNodeByFullName($target["class"]);
                $str .= str_replace(
                                array("{varName}", "{className}", "{idField}"), 
                                array($target["name"], $target["class"], $model->idField), 
                                $this->template["newModel"]);
            } else {
                $str = $str . str_replace(
                                array("{varName}"), 
                                array($target["name"]), 
                                $this->template["newObject"]);
                $model = DM\DataNodeDescription::getNodeByFullName($target["model"]);
            }
            $allItems = isset($target["allItems"]) && $target["allItems"]==="True"; 
            foreach ($model->items as $item) {
                $str .= $this->mapPart($target, $item);
                $itemCfg = null;
            }
        }
        file_put_contents(self::$outputPath.$this->helper["outPutName"].".php", $str);
        
    }
    private function mapPart($target, $item) {
        $str = "";
        $map = null;
        $itemCfg = null;
        if (isset($target["items"][$item->name])) {
            $itemCfg = $target["items"][$item->name];
        }
        
        if($itemCfg){
            if (isset($itemCfg["map"])) {
                $map = $itemCfg["map"];
                if (is_array($map) && count($map) === 1) $map = $map[0];
            } else {
                $map = $item->name;
            }
        }else {
            $allItems = isset($target["allItems"]) && $target["allItems"]==="True"; 
            if ($allItems) {
                $map = $item->name;
            }
        }
        if ($map === null) {
            return "";
        }
        $str = $str . '$v = null;' . "\r\n";
        if($itemCfg !== null && !isset($itemCfg->directFromInput)){
            if (is_array($map) && count($map) > 1) {
                foreach ($map as $m) {
                    $str = $str . str_replace("{m}", $m, $this->template["getVs"]);
                }
            } else {
                $str = $str . str_replace("{m}", $map, $this->template["getV"]);
            }
            if (isset($itemCfg["default"])) {
                $str = $str . str_replace(array("{dataType}", "{default}"), array($item->dataType, $itemCfg["default"]), $this->template["setDefault"]);
            }
        }
        
        $str = $str . $this->specialPart($target , $item);
        
        $str = $str . str_replace(
            array("{varName}", "{itemName}", "{value}"), array($target["name"], $item->name, '$v'), $this->template["setItem"]);
        
        return $str;
    }

    private function specialPart($target , $item){
        if (!isset($target["items"][$item->name])) return "";
        if (!isset($target["items"][$item->name]["special"])) return "";
        $specialCfg = $target["items"][$item->name]["special"];
        
        if($specialCfg["type"] === "function"){
            $name = $specialCfg["name"];
            if(!ends_with($specialCfg["name"],")")){
                $specialCfg["name"].="()";
            }
            $str = '$v = '.$specialCfg["name"].";\r\n";
            return $str;
        }
        if($specialCfg["type"] === "inLineFunction"){
            $name = $specialCfg["name"];
            if(!ends_with($specialCfg["name"],")")){
                $specialCfg["name"].='($v)';
            }
            $str = '$v = '.$specialCfg["name"].";\r\n";
            return $str;
        }
        if($specialCfg["type"] === "server"){
            $name = $specialCfg["name"];
            $str = '$v = $_SERVER["'.$specialCfg["name"]."\"];\r\n";
            return $str;
        }
        
        
        return "";
    }
    private $template = array(
        "newModel" => array('${varName} = new {className}();','${varName}->{idField} = uniqid();'),
        "newModelDescritption" => '   ${varName} = new \\stdClass()'."\r\n",
        "newObject" => '   ${varName} = new \\stdClass();'."\r\n",
        "initNull" => '   ${varName}->{itemName}=null;'."\r\n",
        "getV" => '   if(Input::has("{m}")){'."\r\n".'      $v=Input::get("{m}");'."\r\n}\r\n",
        "getVs" => '   if(!isset($v) && Input::has("{m}")){'."\r\n".'       $v=Input::get("{m}");'."\r\n}\r\n",
        "setItem" => '   ${varName}->{itemName}={value};'."\r\n",
        "setDefault" =>'   if(!isset($v))$v= \BLL\DataModel\DataType::getValueFromString("{dataType}", "{default}" );'."\r\n",
    );
}
